package metier.jdbc.note;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;

import javax.swing.JOptionPane;

import metier.Eleve;
import metier.Matiere;
import metier.MatiereCategorie;
import metier.NoteEleve;
import metier.jdbc.stage.StageJdbc;
import configuration.MessageAppli;

public class NoteEleveJdbc {

	/**
	 * Ajout une note en base.
	 * 
	 * @param Connection
	 *            connexion à la base
	 * @param NoteEleve
	 *            la note a inserer pour l'éleve
	 * @return boolean
	 */
	public static boolean ajouter(Connection c, NoteEleve noteEleve) {
		// préparer la requete sql
		// retourne un entier égal à 1
		// si l’insertion en base de données a été réalisée
		int res = 0;
		try {
			PreparedStatement ps = c
					.prepareStatement("INSERT INTO noteeleve (IDELEVE, IDMATIERE, DATENOTE, NOTE) VALUES (?,?,?,?) ");
			// affecter les values correspondant aux colonnes
			ps.setInt(1, noteEleve.getIdEleve());
			ps.setInt(2, noteEleve.getIdMatiere());
			ps.setDate(3, new java.sql.Date(noteEleve.getDateNote().getTime()));
			ps.setDouble(4, noteEleve.getNote());

			res = ps.executeUpdate();
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
					MessageAppli.MSG_BDD_ERREUR_REQUETE,
					MessageAppli.MSG_BDD_TITRE_ERREUR,
					JOptionPane.ERROR_MESSAGE);
		}
		return res == 1;
	}
	
	/**
	 * Verifie une note en base.
	 * 
	 * @param Connection
	 *            connexion à la base
	 * @param NoteEleve
	 *            la note a inserer pour l'éleve
	 * @return boolean
	 */
	public static NoteEleve verifieByEleveByMatiereByDate(Connection c, NoteEleve noteEleve) {
		NoteEleve ne = null;
		try {
			PreparedStatement ps = c
					.prepareStatement("SELECT * FROM noteeleve WHERE IDELEVE = ? " +
							"AND IDMATIERE=? AND DATENOTE=?");
			// affecter les values correspondant aux colonnes
			ps.setInt(1, noteEleve.getIdEleve());
			ps.setInt(2, noteEleve.getIdMatiere());
			ps.setDate(3, new java.sql.Date(noteEleve.getDateNote().getTime()));
			
			
			ResultSet res = ps.executeQuery();
			
			while (res.next()) {
				ne = new NoteEleve(res.getInt("IDELEVE"), res
						.getInt("IDMATIERE"), res.getDate("DATENOTE"), res
						.getFloat("NOTE"));
				
			}
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
					MessageAppli.MSG_BDD_ERREUR_REQUETE,
					MessageAppli.MSG_BDD_TITRE_ERREUR,
					JOptionPane.ERROR_MESSAGE);
		}
		return ne;
	}
	
	/**
	 * Verifie une note en base, si celle-ci est deja rentre ou pas
	 * @param c
	 * @param noteEleve
	 * @return boolean
	 */
	
	public static Boolean noteEleveExiste(Connection c,NoteEleve noteEleve) {
		return verifieByEleveByMatiereByDate(c,noteEleve)!=null;
	}

	/**
	 * Permet de modifier une note d'un eleve.
	 * 
	 * @param c
	 * @param noteEleve
	 * @return
	 */
	public static boolean modifier(Connection c, NoteEleve noteEleve) {
		int res = 0;
		if (noteEleve.getIdEleve() != null) {
			try {
				PreparedStatement ps = c
						.prepareStatement("UPDATE noteeleve set NOTE = ? "
								+ " WHERE idEleve = ?" + " AND IDMATIERE = ?"
								+ " AND DATENOTE = ?");
				// affecter les values correspondant aux colonnes
				ps.setDouble(1, noteEleve.getNote());
				ps.setInt(2, noteEleve.getIdEleve());
				ps.setInt(3, noteEleve.getIdMatiere());
				ps.setDate(4, new java.sql.Date(noteEleve.getDateNote()
						.getTime()));
				res = ps.executeUpdate();
				ps.close();
				return res == 1;
			} catch (SQLException e) {
				e.printStackTrace();
				JOptionPane.showMessageDialog(null,
						MessageAppli.MSG_BDD_ERREUR_REQUETE,
						MessageAppli.MSG_BDD_TITRE_ERREUR,
						JOptionPane.ERROR_MESSAGE);
			}
		}
		return false;
	}

	/**
	 * Permet de supprimer une note d'un eleve.
	 * 
	 * @param c
	 * @param noteEleve
	 * @return
	 */
	public static boolean supprimer(Connection c, NoteEleve noteEleve) {
		try {
			PreparedStatement ps = c
					.prepareStatement("DELETE FROM noteeleve WHERE IDELEVE = ?  AND IDMATIERE = ? AND DATENOTE=?");

			// affecter les values correspondant aux colonnes
			ps.setInt(1, noteEleve.getIdEleve());
			ps.setDouble(2, noteEleve.getIdMatiere());
			ps.setDate(3, new java.sql.Date(noteEleve.getDateNote().getTime()));

			int res = ps.executeUpdate();
			ps.close();
			return res == 1;
		} catch (SQLException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
					MessageAppli.MSG_BDD_ERREUR_REQUETE,
					MessageAppli.MSG_BDD_TITRE_ERREUR,
					JOptionPane.ERROR_MESSAGE);
		}
		return false;
	}

	/**
	 * Permet de rechercher tous les notes d'un eleve.
	 * 
	 * @param Connection
	 *            connexion à la base
	 * @param eleve
	 *            à rechercher
	 * @return stage
	 */
	public static ArrayList<NoteEleve> getListNoteParEleve(Connection c,
			int idEleve) {
		ArrayList<NoteEleve> listeNoteEleve = new ArrayList<NoteEleve>();
		// préparer la requete sql
		try {
			String requete = "SELECT * FROM noteeleve " + "WHERE IDELEVE = "
					+ idEleve;

			PreparedStatement ps = c.prepareStatement(requete);
			ResultSet res = ps.executeQuery();
			while (res.next()) {
				listeNoteEleve.add(new NoteEleve(res.getInt("IDELEVE"), res
						.getInt("IDMATIERE"), res.getDate("DATENOTE"), res
						.getFloat("NOTE")));
			}
			
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
					MessageAppli.MSG_BDD_ERREUR_REQUETE,
					MessageAppli.MSG_BDD_TITRE_ERREUR,
					JOptionPane.ERROR_MESSAGE);
		}
		return listeNoteEleve;
	}
	
	/**
	 * Permet de rechercher tous les notes d'un eleve pour une matiere.
	 * 
	 * @param Connection
	 *            connexion à la base
	 * @param eleve
	 *            à rechercher
	 * @return stage
	 */
	public static ArrayList<NoteEleve> getListNoteEleveByMatiere(Connection c,
			Eleve eleve,Matiere matiere) {
		ArrayList<NoteEleve> listeNoteEleve = new ArrayList<NoteEleve>();
		// préparer la requete sql
		try {
			String requete = "SELECT * FROM noteeleve WHERE IDELEVE = ? AND IDMATIERE = ?";

			PreparedStatement ps = c.prepareStatement(requete);
			
			ps.setInt(1, eleve.getIdEleve());
			ps.setInt(2, matiere.getIdMatiere());
			
			ResultSet res = ps.executeQuery();
			while (res.next()) {
				listeNoteEleve.add(new NoteEleve(res.getInt("IDELEVE"), res
						.getInt("IDMATIERE"), res.getDate("DATENOTE"), res
						.getFloat("NOTE")));
			}
			
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null,
					MessageAppli.MSG_BDD_ERREUR_REQUETE,
					MessageAppli.MSG_BDD_TITRE_ERREUR,
					JOptionPane.ERROR_MESSAGE);
		}
		return listeNoteEleve;
	}
	
	
			

			

	
	/**
	 * Retourne la moyenne generale d'un eleve.
	 * @param c
	 * @param eleve
	 * @return
	 */
	public static Double getMoyenne(Connection c, Eleve eleve) {
		// Recuperation ds notes de l'eleves.
		ArrayList<NoteEleve> lNoteEleve = getListNoteParEleve(c, eleve.getIdEleve());
		
		// On tri par matiere.
		Collections.sort(lNoteEleve);
		
		// Recuperation de la categorie du stage de l'eleve.
		Integer idCategorie = StageJdbc.rechercherIdCatetgorie(c, eleve.getIdStage());
		
		// Recuperation des coefs des matieres.
		ArrayList<MatiereCategorie> matCat = MatiereCategorieJdbc.getCoefByCategorie(c, idCategorie);
		
		double sommeTotale = 0.0;
		int nbCoef = 0;
		for (NoteEleve noteEleve : lNoteEleve) {
			for (MatiereCategorie matiereCategorie : matCat) {
				if ( noteEleve.getIdMatiere() == matiereCategorie.getIdMatiere()){
					sommeTotale += noteEleve.getNote() * matiereCategorie.getCoef();
					nbCoef += matiereCategorie.getCoef();
					break;
				}
			}
		}
		
		// Calcul de la moyenne
		Double moy = null;
		if ( nbCoef != 0 ){
			moy = sommeTotale / nbCoef;
		}
		return moy;
	}
}
